package com.alibaba.citrus.cr.mn.order.center.facade.function.convert;

import com.alibaba.citrus.cr.common.enums.GeneralStatusEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.OrderCategoryEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.OrderChannelEnum;
import com.alibaba.citrus.cr.common.util.DateUtils;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONValidator;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.crb2btradecenter.obtcsaleorderindex.model.ObtcSaleOrderIndex;
import com.epoch.app.crb2btradecenter.obtcsaleorderlineindex.model.ObtcSaleOrderLineIndex;
import com.epoch.app.mnordercenter.model.dto.ReturnOrderAtomQueryDetailResponse;
import com.epoch.app.mnordercenter.model.dto.ReturnOrderAtomQueryResponse;
import com.epoch.app.mnordercenter.model.dto.SalesOrderAtomQueryDetailResponse;
import com.epoch.app.mnordercenter.model.dto.SalesOrderAtomQueryResponse;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangxiaorui
 * @ClassName ObtcSaleOrderIndexToSalesOrderAtomQueryResponseConvertor
 * @description: TODO
 * @date 2023/05/19 19:42
 * @version: 1.0
 */
public class ReturnOrderIndexToSalesOrderAtomQueryResponseConvertor {

    private static final Log log = Log.getLogger(ReturnOrderIndexToSalesOrderAtomQueryResponseConvertor.class);

    public static List<ReturnOrderAtomQueryResponse> convertMainOrder(Result<List<ObtcSaleOrderIndex>> listResult) {

        if(Objects.isNull(listResult) || !listResult.isSuccess() || CollectionUtils.isEmpty(listResult.getResult())) {
            return Lists.newArrayList();
        }
        return listResult.getResult().stream()
                .map(ReturnOrderIndexToSalesOrderAtomQueryResponseConvertor::convertMainOrder)
                .collect(Collectors.toList());
    }

    public static List<ReturnOrderAtomQueryResponse> convert(Result<List<ObtcSaleOrderIndex>> listResult, Result<List<ObtcSaleOrderLineIndex>> lineResult) {

        if(Objects.isNull(listResult) || !listResult.isSuccess() || CollectionUtils.isEmpty(listResult.getResult())) {
            return Lists.newArrayList();
        }

        List<ObtcSaleOrderLineIndex> lineIndexList = Objects.isNull(lineResult) ? Lists.newArrayList() : lineResult.getResult();
        Map<Long, List<ObtcSaleOrderLineIndex>> lineIndexMap =
                Optional.ofNullable(lineIndexList).orElse(Lists.newArrayList())
                        .stream()
                        .collect(Collectors.groupingBy(ObtcSaleOrderLineIndex::getMainId));

        return listResult.getResult().stream()
                .map(lineResp->{
                    Long mainOrderId = lineResp.getMainId();
                    List<ObtcSaleOrderLineIndex> currMainOrderLine = lineIndexMap.get(mainOrderId);
                    List<ReturnOrderAtomQueryDetailResponse> detailResponses = Optional.ofNullable(currMainOrderLine)
                            .orElse(Lists.newArrayList()).stream()
                            .map(ReturnOrderIndexToSalesOrderAtomQueryResponseConvertor::convertOrderLine)
                            .collect(Collectors.toList());
                    ReturnOrderAtomQueryResponse response = convertMainOrder(lineResp);
                    response.setOrderDetails(detailResponses);
                    return response;
                })
                .collect(Collectors.toList());
    }

    @NotNull
    private static ReturnOrderAtomQueryDetailResponse convertOrderLine(ObtcSaleOrderLineIndex orderLine) {
        ReturnOrderAtomQueryDetailResponse detailResponse = new ReturnOrderAtomQueryDetailResponse();
        detailResponse.setCloseCode(orderLine.getSubRefuseReasonCode());
        detailResponse.setCloseMsg(orderLine.getSubRefuseReasonName());
        detailResponse.setDeliveryFactoryCode(orderLine.getSubDeliveryFactoryCode());
        detailResponse.setDeliveryFactoryName(orderLine.getSubDeliveryFactoryName());
        detailResponse.setIsClose(String.valueOf(orderLine.getSubClosed()));
        detailResponse.setIsCloseName(GeneralStatusEnum.descByCode(orderLine.getSubClosed()));
        detailResponse.setLineNum(orderLine.getSubLineNum());
        detailResponse.setNote(orderLine.getSubRemark());
        detailResponse.setOutLineNum(orderLine.getSubOuterOrderLineId());
        //detailResponse.setProduceDate(orderLine.getSubProductationTime());
        detailResponse.setProductBarCode(orderLine.getSubProductBarCode());
        detailResponse.setProductCode(orderLine.getSubScItemOutCode());
        detailResponse.setProductName(orderLine.getSubScItemTitle());
        detailResponse.setSalesUnitCode(orderLine.getSubSaleUnit());
        detailResponse.setSalesUnitName(orderLine.getSubSaleUnitName());
        detailResponse.setSourceLineNum(orderLine.getSubSourceLineNum());
        detailResponse.setStockCode(orderLine.getSubStockCode());
        detailResponse.setStockConversionNum(orderLine.getSubStockConversionNum());
        detailResponse.setStockName(orderLine.getSubStockName());
        detailResponse.setStockUnitCode(orderLine.getSubInventoryUnitCode());
        detailResponse.setStockUnitName(orderLine.getSubInventoryUnit());
        detailResponse.setTotalAmount(orderLine.getSubShouldPayFee());
        detailResponse.setUnitConversionRelationship(orderLine.getSubUnitConvert());
        detailResponse.setUnitPrice(orderLine.getSubUnitPrice());
        detailResponse.setManualPrice(orderLine.getSubManualPrice());
        detailResponse.setManualTotalAmount(orderLine.getSubManualTotalAmount());
        detailResponse.setInnerProductCode(orderLine.getSubInnerProductCode());
        detailResponse.setInnerProductName(orderLine.getSubInnerProductName());
        detailResponse.setShippingWarehouseCode(orderLine.getSubShippingWarehouseOutCode());
        detailResponse.setShippingWarehouseName(orderLine.getSubShippingWarehouseName());
        detailResponse.setBizFeatures(orderLine.getSubBizFeatures());
        detailResponse.setCumulativeDeliveryQuantity(new BigDecimal(StringUtils.defaultString(orderLine.getSubDeliveryAmount(), "0")).longValue());
        detailResponse.setCumulativePlanDeliveryQuantity(new BigDecimal(StringUtils.defaultString(orderLine.getSubCumulativeDeliveryQuantity(), "0")).longValue());
        // 从 feature中获取创建人、修改人、组织Code信息
        refreshOrderLineInfo4Features(orderLine, detailResponse);

        return detailResponse;
    }

    @NotNull
    private static ReturnOrderAtomQueryResponse convertMainOrder(ObtcSaleOrderIndex order) {
        ReturnOrderAtomQueryResponse response = new ReturnOrderAtomQueryResponse();
        response.setBusinessChannel(order.getMainChannelCode());
        response.setBusinessChannelName(order.getMainChannelName());
        response.setCreateTime(DateUtils.toDateStr(order.getMainGmtCreate(), DateUtils.DATETIME_FORMAT));
        response.setCreatorCode(order.getMainCreatorCode());
        response.setCreatorName(order.getMainCreatorName2());
        response.setCustomerCode(order.getMainCustomerCode());
        response.setCustomerName(order.getMainCustomerName());
        response.setCustomerPurchaseDate(DateUtils.toDateStr(order.getMainCustomerPurchaseDate(), DateUtils.DATE_FORMAT));
        response.setCustomerPurchaseOrderNo(order.getMainCustomerReferenceNo());
        response.setDeliveryMethodCode(order.getMainTransportModeCode());
        response.setDeliveryMethodName(order.getMainTransportModeName());
        response.setExpectedDeliveryDate(DateUtils.toDateStr(order.getMainCustomerExpectDate(), DateUtils.DATE_FORMAT));
        response.setFromSys(order.getMainFromSys());
        response.setModifierCode(order.getMainModifierCode());
        response.setModifierName(order.getMainModifierName2());
        response.setModifierTime(DateUtils.toDateStr(order.getMainGmtModified(), DateUtils.DATETIME_FORMAT));
        response.setNote(order.getMainRemark());
        response.setOrderReasonCode(order.getMainCreateReason());
        response.setOrderReasonName(order.getMainCreateReasonName());
        response.setOrderStatus(String.valueOf(order.getMainStatus()));
        response.setOutOrderNo(order.getMainOuterOrderId());
        response.setProductGroupCode(order.getMainProductGroupCode());
        response.setProductGroupName(order.getMainProductGroupName());
        response.setSalesChannelCode(order.getMainSaleChannelOutCode());
        response.setSalesChannelName(order.getMainSaleChannelName());
        response.setSalesDepartmentCode(order.getMainSaleChannelOutCode());
        response.setSalesDepartmentName(order.getMainDepartmentName());
        response.setSalesOrderNo(order.getMainOrderBizId());
        response.setSalesOrderType(order.getMainOrderType());
        response.setSalesOrderTypeName(order.getMainOrderTypeName());
        response.setSalesOrganizationCode(order.getMainOrganizationOutCode());
        response.setSalesOrganizationName(order.getMainOrganizationName());
        response.setShippingWarehouseCode(order.getMainWareHouseOutCode());
        response.setShippingWarehouseName(order.getMainWareHouseName());
        response.setShipToPartyCode(order.getMainReceiveAddressCode());
        response.setShipToPartyName(order.getMainReceiveDetailAddress());
        response.setSourceOrderNo(order.getMainSourceOrderNo());
        response.setBusinessType(order.getMainBusinessType());
        response.setBusinessTypeName(order.getMainBusinessTypeName());
        response.setBusinessUnitCode(order.getMainBisUnitOutCode());
        response.setBusinessUnitName(order.getMainBisUnitName());
        response.setBizFeatures(order.getMainBizFeatures());
        response.setOriginalOrderNo(order.getMainOriginalOrderNo());
        response.setFulfillmentTypeCode(order.getMainFulfillmentTypeCode());
        response.setFulfillmentPriority(order.getMainFulfillmentPriority());
        response.setAutoFulfillment(order.getMainAutoFulfillment());
        response.setReceiveWarehouseCode(order.getMainReceiveWarehouseCode());
        response.setReceiveWarehouseName(order.getMainReceiveWarehouseName());
        response.setKaArea(order.getMainKaArea());
        response.setKaSystem(order.getMainKaSystem());
        if(StringUtils.isNotBlank(order.getSubDeliveryFactoryCode())){
            String[] deliveryFactoryArray = order.getSubDeliveryFactoryCode().replace("[","").replace("]","").split(",");
            if(deliveryFactoryArray.length > 0){
                response.setDeliveryFactoryCode(deliveryFactoryArray[0]);
            }
        }
        response.setDeliveryFactoryName("");
        if(StringUtils.isNotBlank(order.getSubStockCode())){
            String[] stockCodeArray = order.getSubStockCode().replace("[","").replace("]","").split(",");
            if(stockCodeArray.length > 0){
                response.setStockCode(stockCodeArray[0]);
            }
        }
        response.setStockName("");
        response.setReceiveFactoryCode(order.getMainReceiveFactoryCode());
        response.setReceiveFactoryName(order.getMainReceiveFactoryName());
        if(StringUtils.isNotBlank(order.getMainOrderBizTag())) {
            response.setOrderBizTag(Arrays.asList(order.getMainOrderBizTag().split(",")));
        }
        response.setOrderCategoryCode(order.getMainOrderCategoryCode());
        OrderCategoryEnum orderCategoryEnum = OrderCategoryEnum.of(order.getMainOrderCategoryCode());
        if(orderCategoryEnum != null) {
            response.setOrderCategoryName(orderCategoryEnum.getDesc());
        }else{
            response.setOrderCategoryName("");
        }
        response.setOrderChannelCode(order.getMainOrderChannelCode());
        if(StringUtils.isNotBlank(order.getMainOrderChannelCode())) {
            response.setOrderChannelName(OrderChannelEnum.of(order.getMainOrderChannelCode()).getDesc());
        }
        // 从 feature中获取创建人、修改人、组织Code信息 等
        refreshMainOrderInfo4Features(order, response);

        return response;
    }

    private static void refreshMainOrderInfo4Features(ObtcSaleOrderIndex order, ReturnOrderAtomQueryResponse response) {
        Map<String, String> featuresMap = JSONObject.parseObject(order.getMainFeatures(), new TypeReference<Map<String, String>>() {});
        featuresMap = Optional.ofNullable(featuresMap).orElse(Maps.newHashMap());

        String creatorCode = featuresMap.getOrDefault("creatorCode", order.getMainCreatorCode());
        String creatorName = featuresMap.getOrDefault("creatorName", order.getMainCreatorName2());
        String modifierCode =featuresMap.getOrDefault("modifierCode", order.getMainModifierCode());
        String modifierName =featuresMap.getOrDefault("modifierName", order.getMainModifierName2());
        response.setCreatorCode(creatorCode);
        response.setCreatorName(creatorName);
        response.setModifierCode(modifierCode);
        response.setModifierName(modifierName);


    }

    private static void refreshOrderLineInfo4Features(ObtcSaleOrderLineIndex orderLineIndex, ReturnOrderAtomQueryDetailResponse response) {
        Map<String, String> featuresMap = JSONObject.parseObject(orderLineIndex.getMainFeatures(), new TypeReference<Map<String, String>>() {});
        featuresMap = Optional.ofNullable(featuresMap).orElse(Maps.newHashMap());
        String manualTotalAmount = featuresMap.getOrDefault("manualTotalAmount", orderLineIndex.getSubManualTotalAmount());
        String logicWarehouseCode = featuresMap.getOrDefault("logicWarehouseCode", orderLineIndex.getSubShippingWarehouseCode());

        response.setManualTotalAmount(manualTotalAmount);
        response.setShippingWarehouseCode(logicWarehouseCode);
    }

    private static String parseUserInfoCode(String dbCreator) {
        if(org.apache.commons.lang.StringUtils.isBlank(dbCreator) || !JSONValidator.from(dbCreator).validate()) {
            return dbCreator;
        }
        log.info("parseUserInfoCode_memberInfo={}", dbCreator);
        Map<String, String> creatorInfo = JSONObject.parseObject(dbCreator, new TypeReference<Map<String, String>>() {});
        return creatorInfo.getOrDefault("empId", dbCreator);
    }
}
